package com.example.mydemo1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mydemo1.utils.QueryWrapperHelper;
import com.example.mydemo1.entity.common.PageParams;
import com.example.mydemo1.entity.common.PageResult;
import com.example.mydemo1.entity.common.AppResp;
import com.example.mydemo1.utils.OrikaBeanMapper;
import com.example.mydemo1.utils.BeanUtil;
import com.example.mydemo1.mapper.SysUserMapper;
import com.example.mydemo1.entity.vo.SysUserVO;
import com.example.mydemo1.entity.po.SysUser;
import com.example.mydemo1.service.SysUserService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户表 业务层接口实现类
 * </p>
 *
 * @createTime: 2023/09/16 14:29:44
 */
@Service("sysUserServiceImpl4mydemo1")
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public AppResp<PageResult<SysUserVO>> page(PageParams<SysUserVO> pageParams) {
        SysUser sysUser = OrikaBeanMapper.map(pageParams.getEntityParams(), SysUser.class);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        try {
            QueryWrapperHelper.getInstance().convert(sysUser, queryWrapper);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            log.error("分页查询参数转换错误", e);
        }

        IPage<SysUser> params = new Page<>();
        params.setCurrent(pageParams.getPageNum());
        params.setSize(pageParams.getPageSize());

        IPage<SysUser> pageResultTmp = sysUserMapper.selectPage(params, queryWrapper);
        List<SysUserVO> sysUserVOs = OrikaBeanMapper.mapAsList(pageResultTmp.getRecords(), SysUserVO.class);

        PageResult<SysUserVO> pr = new PageResult<>();
        pr.setCurrent(pageResultTmp.getCurrent());
        pr.setPages(pageResultTmp.getPages());
        pr.setSize(pageResultTmp.getSize());
        pr.setTotal(pageResultTmp.getTotal());
        pr.setRecords(sysUserVOs);
        return AppResp.success(pr);
    }

    @Override
    public AppResp<SysUserVO> queryById(String sysUserId) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();

        SysUser sysUser = sysUserMapper.selectById(sysUserId);
        if (ObjectUtils.isEmpty(sysUser)) {
            return AppResp.error("您查询的记录不存在，操作失败");
        }

        SysUserVO sysUserVO = OrikaBeanMapper.map(sysUser, SysUserVO.class);
        return AppResp.success(sysUserVO);
    }

    @Override
    public AppResp<Void> add(SysUserVO sysUserVO) {
        SysUser sysUser = OrikaBeanMapper.map(sysUserVO, SysUser.class);
        // TODO 如果插入前需要根据某个属性判断对象是否存在，请修改下面代码：
        /*
        List<SysUser> coreSysUsers = sysUserMapper.selectList(new QueryWrapper<SysUser>().lambda()
            .eq(SysUser::getAccount, sysUser.getAccount()));
        if (!ObjectUtils.isEmpty(coreSysUsers)) {
            return AppResp.error("已存在[" + sysUser.getAccount() + "]记录，添加失败");
        }
        */
        // TODO 逻辑删除
        //sysUser.setDeleteFlag(false);
        //sysUser.setCreateAt(LocalDateTime.now());
        //sysUser.setCreateBy("admin");
        return sysUser.insert() ? AppResp.success() : AppResp.error("操作失败，请重试");
    }

    @Override
    public AppResp<Void> delById(String sysUserId) {
        SysUser sysUser = sysUserMapper.selectById(sysUserId);
        if (ObjectUtils.isEmpty(sysUser)) {
            return AppResp.error("删除的对象不存在，操作失败");
        }
        // TODO 逻辑删除
        //sysUser.setDeleteFlag(true);
        //sysUser.setUpdateAt(LocalDateTime.now());
        // TODO 需要改为当前登录的人
        //sysUser.setUpdateBy("admin");
        return sysUser.updateById() ? AppResp.success() : AppResp.error("操作失败，请重试");

        // 下面是真实删除的代码，可以根据需要放开
        /*
        int i = sysUserMapper.deleteById(sysUserId);
        return i > 0 ? AppResp.success() : AppResp.error("操作失败，没有该记录");
        */
    }

    @Override
    public AppResp<Void> modify(SysUserVO sysUserVO) {
        SysUser sysUser = OrikaBeanMapper.map(sysUserVO, SysUser.class);

        SysUser existSysUser = sysUserMapper.selectById(sysUser.getId());
        if (ObjectUtils.isEmpty(existSysUser)) {
            return AppResp.error("不存在[" + sysUser.getId() + "]记录，操作失败");
        }

        try {
            // 将新对象sysUser的值覆盖旧对象existSysUser的值
            BeanUtil.merge(sysUser, existSysUser);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return AppResp.error("操作失败，"+e.getMessage());
        }

        //existSysUser.setUpdateAt(LocalDateTime.now());
        //existSysUser.setUpdateBy("admin");
        return existSysUser.updateById() ? AppResp.success() : AppResp.error("操作失败，请重试");
    }

    @Override
    public AppResp<Void> batchAdd(List<SysUserVO> sysUserVos) {
        List<SysUser> sysUsers = OrikaBeanMapper.mapAsList(sysUserVos, SysUser.class);

        // 分批插入，没批插入200条
        Lists.partition(sysUsers, 200).forEach(subSysUsers -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysUserMapper mapper = session.getMapper(SysUserMapper.class);
                // ExecutorType.BATCH，单条插入
                //for (SysUser subSysUser : sysUsers) {
                //    mapper.insert(subSysUser);
                //}
                // ExecutorType.BATCH，批量插入，很多时候比上面的方式快很多
                mapper.batchInsert(subSysUsers);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }

    @Override
    public AppResp<Void> batchModify(List<SysUserVO> sysUserVos) {
        List<SysUser> sysUsers = OrikaBeanMapper.mapAsList(sysUserVos, SysUser.class);

        // 分批插入，没批插入200条
        Lists.partition(sysUsers, 200).forEach(subSysUsers -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysUserMapper mapper = session.getMapper(SysUserMapper.class);
                // ExecutorType.BATCH，单条
                //for (SysUser subSysUser : sysUsers) {
                //    mapper.updateById(subSysUser);
                //}
                // ExecutorType.BATCH，批量，比单条快，需要在url中配置allowMultiQueries=true
                mapper.batchModify(subSysUsers);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }

    /**
     * 这个是物理删除，注意
     */
    @Override
    public AppResp<Void> batchDelete(List<SysUserVO> sysUserVos) {
        List<SysUser> sysUsers = OrikaBeanMapper.mapAsList(sysUserVos, SysUser.class);

        // 分批插入，没批插入200条
        Lists.partition(sysUsers, 200).forEach(subSysUsers -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysUserMapper mapper = session.getMapper(SysUserMapper.class);
                // ExecutorType.BATCH，单条
                //for (SysUser subSysUser : sysUsers) {
                //    mapper.deleteById(subSysUser);
                //}
                // ExecutorType.BATCH，批量
                mapper.batchDelete(subSysUsers);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }
}
